package com.tang.param_check.aspect;

import com.tang.param_check.aspect.annotation.MultiParamCheck;
import com.tang.param_check.aspect.handler.HandlerManager;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 参数校验的切面类，校验所有的controller的数据
 *
 * @Author tangyuan2meicloud.com
 * @DATE 2021/12/17 20:24
 * @Desc
 * @Remarks
 */
@Slf4j
@Aspect
@Component
public class MultiParamAspect {

    @Autowired
    private HandlerManager handlerManager;

    @Pointcut("@annotation(com.tang.param_check.aspect.annotation.MultiParamCheck)")
    public void pointCut() {
    }

    /**
     * @param point
     * @throws Exception
     */
    @Before("pointCut()")
    public void beforeMethod(JoinPoint point) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        MultiParamCheck annotation = method.getAnnotation(MultiParamCheck.class);
        /**
         * 处理类
         */
        Class[] classes = annotation.handlerNames();
        if (classes == null || classes.length < 1) {
            return;
        }
        /**
         * 参数序号
         */
        int[] numbers = annotation.serialNumbers();
        if (numbers == null || numbers.length < 1) {
            return;
        }

        /**
         * 参数
         */
        Object[] args = point.getArgs();
        if (args == null || args.length < 1) {
            return;
        }

        for (int i = 0; i < numbers.length; i++) {
            if (i > classes.length - 1) {
                break;
            }
            /**
             * 获取处理类
             */
            Class handlerClass = classes[i];
            int index = numbers[i];
            if (index > args.length - 1) {
                continue;
            }
            Object arg = args[index];
            if (!handlerManager.paramCheckHandler(handlerClass, arg)) {
                throw new RuntimeException("处理失败！处理类:" + handlerClass.getName() + "参数：" + arg);
            }
        }
    }

}
